﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using SharpWebSocket.Protocol;
using System.Threading;

namespace SharpWebSocket
{
    public class WebSocketHandler
    {
        #region Construct & Internal Member
        protected internal WebSocketHandler()
        {
        }

        /*protected internal WebSocketHandler( WebSocketContext context, Socket clientSocket )
        {
            ClientSocket = clientSocket;
            Context = context;
        }*/

        internal void Init( WebSocketContext context, Socket clientSocket )
        {
            ClientSocket = clientSocket;
            Context = context;
        }

        private WebSocketContext Context
        {
            get;
            set;
        }

        protected Socket ClientSocket
        {
            get;
            set;
        }
        #endregion

        #region Event & Event Raiser
        public event EventHandler Error;

        public event WebSocketConnected WebSocketConnected;

        public event DataReceived DataReceived;

        public event SocketClosed SocketClosed;

        protected internal virtual void OnError( EventArgs e )
        {
            if (Error != null)
            {
                Error( this, e );
            }
        }

        protected internal virtual void OnWebSocketConnected( WebSocketConnectedEventArgs e )
        {
            if (WebSocketConnected != null)
            {
                WebSocketConnected( this, e );
            }
        }

        protected internal virtual void OnSocketClsoed( SocketClosedEventArgs e )
        {
            if (SocketClosed != null)
            {
                SocketClosed( this, e );
            }
        }

        protected internal virtual void OnDataReceived( DataReceivedEventArgs e )
        {
            if (DataReceived != null)
            {
                DataReceived( this, e );
            }
        }
        #endregion

        #region Assistant
        public int Send( string senddata )
        {
            int sendCount = 0;
            try
            {
                byte[] data = Draft10.WrapResponse( senddata );
                sendCount = ClientSocket.Send( data );

                return sendCount;
            }
            catch
            {
                OnError( EventArgs.Empty );
                Disconnect();

                // never called
                return 0;
            }
        }

        public string Receive()
        {
            return string.Empty;
        }

        public void Broadcast(string str)
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <exception cref="WebSocketCloseException"></exception>
        public void Disconnect()
        {
            ClientSocket.Shutdown( SocketShutdown.Both );
            ClientSocket.Close();

            try
            {
                OnSocketClsoed( new SocketClosedEventArgs( ClientSocket, SocketError.Success ) );
            }
            catch
            {
                // TODO log
            }
            finally
            {
                throw new WebSocketCloseException();
            }
        }
        #endregion
    }
}
